const http = require('http');
const https = require('https');
const path = require('path');
const fs = require('fs');

export function otherDownFile(
  url: string,
  localPath: string,
  timeout = 10 * 1000
) {
  return _outherDownFile(url, localPath, timeout);
}
export function _outherDownFile(
  url: string,
  localPath: string,
  timeout = 10 * 1000,
  tryTime = 1
) {
  let flag = false;
  return new Promise((_resolve, _reject) => {
    function resolve(data) {
      if (flag) return;
      flag = true;
      clearTimeout(timer);
      console.count('下载完成:');
      safeClose();
      return _resolve({ url, localPath, data });
    }
    function reject(data) {
      if (flag) return;
      flag = true;
      clearTimeout(timer);
      safeClose();
      return _reject({ url, localPath, data });
    }
    function safeClose() {
      try {
        handle.abort();
      } catch (e) {}
    }
    let timer = setTimeout(() => {
      reject({
        delete: false,
        data: '超时'
      });
      safeClose();
    }, timeout);
    let handle;
    try {
      handle = (url.includes('https://') ? https : http)
        .get(url, res => {
          // 重新计时
          clearTimeout(timer);
          timer = setInterval(() => {
            reject({
              delete: false,
              data: '超时'
            });
            safeClose();
          }, timeout);
          let error;
          if (res.statusCode !== 200) {
            error = {
              delete: true,
              error: res.statusCode
            };
          }
          if (error) {
            res.resume();
            reject(error);
            return;
          }
          let { dir, root, base, name, ext } = path.parse(localPath);
          mkdir(dir);
          let writer = fs.createWriteStream(localPath);
          res.pipe(writer);
          res.on('end', () => {
            resolve('完成');
          });
          res.on('error', e => {
            reject({
              error: e,
              delete: false
            });
          });
        })
        .on('error', e => {
          reject({
            error: e,
            delete: false
          });
        })

        .on('aborted', e => {
          reject({
            error: e,
            delete: false
          });
          reject(e);
        })
        .on('timeout', e => {
          reject({
            error: e,
            delete: false
          });
          reject(e);
        });
    } catch (e) {
      reject({
        error: e,
        delete: false
      });
    }
  });
}
function mkdir(dir) {
  let dirs = dir.split('/');
  dirs.map((item, index) => {
    let dirPath = dirs.slice(0, index + 1).join('/');
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath);
    }
  });
}
